package chess.piece;

import javax.swing.ImageIcon;
import java.util.ArrayList;
import chess.Position;
import chess.Status;

/**
 * Classe King (Rei)
 * @author Beatriz Miho Anami
 * @author Lucas Rodrigues Anizelli
 * @author Marcos Okamura Rodrigues
 */
public final class King extends Piece implements MoveMemory{
	private boolean hasMoved;
	
	/**
	 * Construtor do Rei.
	 * @param id		id do rei
	 * @param position	posição do rei
	 * @param color		cor do rei
	 * @param imageIcon	imageIcon do rei
	 */
	public King(int id, Position position, int color, ImageIcon imageIcon) {
		super(id, position, color, imageIcon);
		this.hasMoved = false;
	}
	
	/**
	 * Modifica a posição do rei.
	 * @param position	nova posição do rei
	 */
	public void setPosition(Position position) {
		super.setPosition(position);
		this.hasMoved = true;
	}

	/**
	 * Retorna a representação do Rei em String.
	 * @return string "K"
	 */
	@Override
	public String toString(){
		return "K";
	}
	
	/**
	 * Verifica se o rei pode capturar uma peça na posição especificada.
	 * @param position	posição da peça a ser capturada
	 * @return 			o status da captura
	 */
	public Status canCapture(Position position){
		int rowDistance = Math.abs(this.position.getRow() - position.getRow());
		int columnDistance = Math.abs(this.position.getColumn() - position.getColumn());
		if((rowDistance <= 1) && (columnDistance <= 1)){
			return Status.CHECK_UNDER_ATTACK;
		} else {
			return Status.NO;
		}
	}

	/**
	 * Verifica se o rei pode ser movido para a posição especificada.
	 * @param position	nova posição do rei
	 * @return 			o status do movimento
	 */
	public Status canMove(Position position){
		int rowDistance = Math.abs(this.position.getRow() - position.getRow());
		int columnDistance = Math.abs(this.position.getColumn() - position.getColumn());
		if((rowDistance <= 1) && (columnDistance <= 1)){
			return Status.CHECK_UNDER_ATTACK;
		} else if(this.position.getRow() == position.getRow()){
			if(position.getColumn() == 2){
				return Status.CHECK_LONG_CASTLING;
			} else if(position.getColumn() == 6){
				return Status.CHECK_SHORT_CASTLING;
			}
		} 
		return Status.NO;
	}

	/**
	 * Retorna o raio de alcance do rei no tabuleiro.
	 * @return	ArrayList com as posições de alcance do rei
	 */
	public ArrayList<Position> getRange(){
		ArrayList<Position> arrayList = new ArrayList<Position>();
		int row = position.getRow();
		int column = position.getColumn();
		for(int i = row -1; i <= row + 1; i++){
			for(int j = column -1; j <= column +1; j++){
				if(i >= 0 && i < NUMBER_OF_ROWS && j >= 0 && j < NUMBER_OF_COLUMNS){
					if(i != row || j!= column){
						arrayList.add(new Position(i, j));
					}
				}
			}
		}
		if(!this.hasMoved){
			arrayList.add(new Position(row, 2));
			arrayList.add(new Position(row, 6));
			
		}
		return arrayList;
	}
	
	/**
	 * Verifica se o rei já se moveu alguma vez durante o jogo.
	 * @return true se o rei realizou algum movimento ou false caso contrário
	 */
	public boolean hasMoved() {
		return this.hasMoved;
	}
}
